package com.snoob.bffAdmin.wConfig.example;//package com.snoob.springboot.wConfig.example;
//
//import lombok.extern.slf4j.Slf4j;
//import org.redisson.Redisson;
//import org.redisson.api.RLock;
//import org.redisson.api.RedissonClient;
//import org.redisson.config.Config;
//import org.redisson.config.SingleServerConfig;
//
//import java.util.concurrent.ArrayBlockingQueue;
//import java.util.concurrent.ExecutorService;
//import java.util.concurrent.ThreadPoolExecutor;
//import java.util.concurrent.TimeUnit;
//
//
///**
// * @描述: 分布式锁
// * @作者: lixing
// * @日期 2021/7/10 17:19
// */
//@Slf4j
//public class ReentrantLockDemo {
//    public static RedissonClient redissonClient;
//
//    static {
//        Config config = new Config();
//        // Redis单节点模式
//        SingleServerConfig singleServerConfig = config.useSingleServer();
//        singleServerConfig.setPassword("LI1234REDIS!");
//        singleServerConfig.setAddress("redis://192.168.213.137:6379");
//        singleServerConfig.setDatabase(0);
//        // 客户端实例
//        redissonClient = Redisson.create(config);
//    }
//
//    public static void main(String[] args) throws InterruptedException {
//        ExecutorService executorService = new ThreadPoolExecutor(
//                10,
//                100,
//                30, TimeUnit.SECONDS,
//                new ArrayBlockingQueue<>(100),
//                new ThreadPoolExecutor.CallerRunsPolicy());
//        /*
//         * 幂等：
//         * 1、通过分布式锁过滤掉短时间内（假设当前业务执行耗时N秒，则N秒内的重复请求都会被过滤掉，但N秒之后的重复请求并不会被过滤）的重复请求
//         * 2、添加数据时，设置主键、联合主键约束，防止重复数据的产生
//         */
//        for (int i = 0; i < 10; i++) {
//            executorService.execute(new Runnable() {
//                @Override
//                public void run() {
//                    RLock rLock = redissonClient.getLock("rLock");
//                    boolean res = false;
//                    try {
//                        /*
//                         * 1、如果需要使用续锁功能，请不要设置锁的过期时间（可以设置成-1），否则RedissonLock就会认为你需要自己控制锁时间而放弃执行续锁逻辑
//                         * 2、RedissonLock的续锁逻辑是用netty下的Timeout定时器来实现的，默认锁时间是30秒，定时器每锁时间/3也就是10秒执行一次。来判断是否还持有锁，如果还持有锁就重置锁时间为30秒。从而避免业务执行时间大于锁时间而导致的锁被释放了的问题
//                         */
//                        // 尝试取锁：
//                        // 1、取锁超时时间 500 毫秒，超过则取锁失败
//                        // 2、取锁成功后，-1表示锁使用默认的有效期30秒（如果业务提前执行完毕也会提前释放锁），每隔30/3（10）秒会自动检测锁是否存在，存在则重置锁的有效期为 30 秒
//                        res = rLock.tryLock(500, -1, TimeUnit.MILLISECONDS);
//                        if (res) {
//                            log.info(Thread.currentThread().getName()+" 拿到锁，开始执行任务");
//                            Thread.sleep(8000);
//                            log.info(Thread.currentThread().getName()+" 拿到锁，执行任务成功");
//                        } else {
//                            log.info(Thread.currentThread().getName()+" 超时，未拿到锁");
//                        }
//                    } catch (InterruptedException e) {
//                        e.printStackTrace();
//                    } finally {
//                        if(rLock.isLocked() && rLock.isHeldByCurrentThread()) {
//                            // 释放锁
//                            rLock.unlock();
//                        }
//                    }
//                }
//            });
//        }
//        // 关闭线程池
//        executorService.shutdown();
//    }
//}
